package com.isoft.service.impl;

import com.isoft.entity.DfmeAfidEntity;
import com.isoft.mapper.DfmeAfidMapper;
import com.isoft.service.DfmeAfidService;
import com.isoft.util.XmlParserUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * DFME-AFID 消息处理服务实现类
 */
@Service
public class DfmeAfidServiceImpl implements DfmeAfidService {
    private static final Logger logger = LoggerFactory.getLogger(DfmeAfidServiceImpl.class);

    private final DfmeAfidMapper dfmeAfidMapper;
    private final XmlParserUtil xmlParserUtil;

    @Autowired
    public DfmeAfidServiceImpl(DfmeAfidMapper dfmeAfidMapper, XmlParserUtil xmlParserUtil) {
        this.dfmeAfidMapper = dfmeAfidMapper;
        this.xmlParserUtil = xmlParserUtil;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String parseAndSave(MultipartFile file) throws IOException {
        try {
            logger.info("开始处理文件上传: 文件名={}, 大小={}字节",
                    file.getOriginalFilename(), file.getSize());

            if (file.isEmpty()) {
                logger.warn("上传文件为空");
                throw new IllegalArgumentException("上传文件不能为空");
            }

            if (!file.getOriginalFilename().toLowerCase().endsWith(".xml")) {
                logger.warn("不支持的文件类型: {}", file.getOriginalFilename());
                throw new IllegalArgumentException("仅支持XML文件");
            }

            String xmlContent = new String(file.getBytes(), StandardCharsets.UTF_8);
            return parseAndSave(xmlContent);
        } catch (IOException e) {
            logger.error("文件读取失败", e);
            throw new IOException("文件处理失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void parseAndSave(DfmeAfidEntity entity) {
        if (entity == null || entity.getDflt() == null) {
            logger.error("无效的实体数据");
            throw new IllegalArgumentException("航班数据不能为空");
        }

        try {
            processFlightData(entity);
        } catch (DataAccessException e) {
            logger.error("数据库操作失败", e);
            throw new RuntimeException("数据处理失败，请稍后重试");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String parseAndSave(String xmlContent) {
        try {
            logger.debug("开始处理XML内容: {}", xmlContent.substring(0, Math.min(100, xmlContent.length())) + "...");

            if (xmlContent == null || xmlContent.trim().isEmpty()) {
                throw new IllegalArgumentException("XML内容不能为空");
            }

            DfmeAfidEntity entity = xmlParserUtil.parseXml(xmlContent, DfmeAfidEntity.class);

            if (entity == null || entity.getDflt() == null) {
                throw new IllegalArgumentException("无效的XML结构");
            }

            if (!entity.isValid()) {
                throw new IllegalArgumentException("缺少必要的字段数据");
            }

            processFlightDataWithFallback(entity);

            return String.format("航班数据处理成功。航班ID: %d, 消息ID: %d",
                    entity.getDflt().getFlightId(), entity.getMsgId());
        } catch (Exception e) {
            logger.error("XML处理失败: {}", e.getMessage());
            throw new RuntimeException("XML处理失败: " + e.getMessage());
        }
    }

    /**
     * 处理航班数据（带降级策略）
     */
    private void processFlightDataWithFallback(DfmeAfidEntity entity) {
        try {
            // 优先尝试自增主键方案
            dfmeAfidMapper.insertMeta(entity);
            logger.debug("使用自增主键方案插入成功，生成的消息ID: {}", entity.getMeta().getMsgId());
        } catch (Exception e) {
            logger.warn("自增主键方案失败，尝试序列方案: {}", e.getMessage());
            try {
                // 次优方案：使用序列
                dfmeAfidMapper.insertMetaWithSequence(entity);
                logger.debug("使用序列方案插入成功，生成的消息ID: {}", entity.getMsgId());
            } catch (Exception ex) {
                logger.warn("序列方案失败，回退到手动ID方案: {}", ex.getMessage());
                // 最后回退方案：手动生成ID
                dfmeAfidMapper.insertMetaWithManualId(entity);
                logger.debug("使用手动ID方案插入成功，生成的消息ID: {}", entity.getMsgId());
            }
        }

        // 处理航班数据
        processFlightData(entity);
    }

    /**
     * 处理航班基础数据
     */
    private void processFlightData(DfmeAfidEntity entity) {
        Long flightId = entity.getDflt().getFlightId();

        try {
            if (dfmeAfidMapper.existsByFlightId(flightId) > 0) {
                int updated = dfmeAfidMapper.updateFlightBase(entity);
                logger.debug("更新航班数据成功，航班ID: {}, 影响行数: {}", flightId, updated);
            } else {
                int inserted = dfmeAfidMapper.insertFlightBase(entity);
                logger.debug("插入航班数据成功，航班ID: {}, 影响行数: {}", flightId, inserted);
            }
            
            // 新增：插入航班异常信息到FLIGHT_IRREGULARITY表
            try {
                dfmeAfidMapper.insertIrregularity(entity);
                logger.debug("插入航班异常信息成功，航班ID: {}", flightId);
            } catch (Exception e) {
                logger.warn("插入航班异常信息失败，航班ID: {}", flightId, e);
            }
        } catch (DataAccessException e) {
            logger.error("航班数据处理失败，航班ID: {}", flightId, e);
            throw new RuntimeException("航班数据保存失败");
        }
    }
}